package com.gryffonx.NameGenerators;

import com.gryffonx.DiceRoller.StaticDiceRoller;
import com.gryffonx.utils.StringUtils;
import com.gryffonx.utils.XMLUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

import java.io.File;


/**
 * Generator class for creating names for use with elven characters.  Process is based around
 * seven seperate properties files containing random "syllables" for use when constructing the name<br>
 * <br>
 * The process runs as follows:  A d2 is rolled to determine the category to start building a name from, either
 * A or B.  After that, another d2 is rolled to decide which subcategory of A or B to use, (1, or 2).  Then a d20 is
 * rolled and corresponded to the appropriate category (A1, A2, B1, or B2).  This makes up the prefix of the name<br>
 * <br>
 * Next another d20 is rolled and matched against the mid category, to get the middle syllable<br>
 * <br>
 * Finally, the gender flag determines the last group, and a d20 is rolled to correspond to it.  This generates the
 * suffix.  All three values are then merged and returned to the client
 *
 * @author Erik Stell
 * @version 1.0
 */
public class ElfNameGenerator {
    private static final File fileToBeParsed = new File("src/com/gryffonx/xml/elf.xml");
    private static String gender = "";
    private static final SAXReader reader = new SAXReader();
    private static Document xmlDoc = null;

    /**
     * @return
     */
    private static String getGender() {
        return gender;
    }

    /**
     * @param gender
     */
    private static void setGender(String gender) {
        ElfNameGenerator.gender = gender;
    }

    public static String generateSurname(){
        try {
            xmlDoc = reader.read(fileToBeParsed);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        StringBuffer retVal = new StringBuffer();
        retVal.append(StringUtils.capitalize(XMLUtils.getNodeValue("surname", xmlDoc, 1)));
        retVal.append(XMLUtils.getNodeValue("surname", xmlDoc, 2));

        return retVal.toString();
    }

    /**
     * @param gender
     * @param howMany
     * @return
     */
    public static String generateName(String gender, int howMany, boolean addTitle, boolean addSurname) throws Exception {
        if (howMany <= 0) {
            howMany = 1;
        }

        try {
            xmlDoc = reader.read(fileToBeParsed);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        setGender(gender);
        StringBuffer retVal = new StringBuffer();

        for (int i = 0; i < howMany; i++) {
            StringBuffer finishedName = new StringBuffer();

            try {
                finishedName.append(getPrefix(determineGroup()));
                finishedName.append(getMid());
                finishedName.append(extractSuffix());
            } catch (Exception e) {
                e.printStackTrace();
            }

            retVal.append(StringUtils.capitalize(finishedName.toString()));
            if (addTitle){
                retVal.append(TitleGenerator.generateName(1));
            }
        }

            if (addSurname){
                retVal.append(" ").append(generateSurname());
            }

        return retVal.toString();
    }

    /**
     * @return
     */
    private static String determineGroup() {
        String groupName = "";

        try {
            int rolld2_1 = StaticDiceRoller.rolldSomething(2, 1);
            int rolld2_2 = StaticDiceRoller.rolldSomething(2, 1);

            if (rolld2_1 == 1) {
                groupName = "A";
            } else {
                groupName = "B";
            }

            if (rolld2_2 == 1) {
                groupName += "1";
            } else {
                groupName += "2";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return groupName;
    }

    /**
     * @return
     */
    private static String extractSuffix() {
        String retVal = "";

        try {
            retVal = XMLUtils.getNodeValue(xmlDoc, getGender().toLowerCase());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return retVal;
    }

    /**
     * @return
     */
    private static String getMid() {
        String retVal = "";
        try {
            retVal = XMLUtils.getNodeValue("middle", xmlDoc, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return retVal;
    }

    /**
     * @param groupName
     * @return
     */
    private static String getPrefix(String groupName) {
        String retVal = "";

        try {

            if (groupName.equals("A1")) {
                retVal = StringUtils.capitalize(XMLUtils.getNodeValue("prefix", xmlDoc, 1));
            } else if (groupName.equals("A2")) {
                retVal = StringUtils.capitalize(XMLUtils.getNodeValue("prefix", xmlDoc, 2));
            } else if (groupName.equals("B1")) {
                retVal = StringUtils.capitalize(XMLUtils.getNodeValue("prefix", xmlDoc, 3));
            } else if (groupName.equals("B2")) {
                retVal = StringUtils.capitalize(XMLUtils.getNodeValue("prefix", xmlDoc, 4));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retVal;
    }
}
